// MRTObject.h: interface for the CMRTObject class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_MRTOBJECT_H__EAEC9766_0B79_4549_85A0_5136D758153A__INCLUDED_)
#define AFX_MRTOBJECT_H__EAEC9766_0B79_4549_85A0_5136D758153A__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "Picture.h"
#include "MEMDC.H"
#include <math.h>
#include <afxtempl.h>
#include "XMLSettings.h"
#include "IULFile.h"

#ifndef _TOOLMAKER
#include "Cell2000.h"
#endif

#define LWLevel(w)      ((BYTE)((w)>>16))
#define LPWidth(w)      ((BYTE)(((WORD)(w)) >> 8))
#define LVWidth(w)		((BYTE)(w))

#define ALIGN_NONE		0x0000
#define ALIGN_LEFT		0x0001
#define ALIGN_CENTER	0x0002
#define ALIGN_RIGHT		0x0004
#define ALIGN_HORZ		0x0008
#define ALIGN_TOP		0x0010
#define	ALIGN_BOTTOM	0x0020
#define ALIGN_VCENTER   0x0040
#define ALIGN_VERT		0x0080
#define SAME_WIDTH		0x0100
#define SAME_HEIGHT		0x0200
#define SAME_SIZE		0x0300
#define ALIGN_RESET		0x1000

#define MRTOBJ_LINE		0x0010
#define MRTOBJ_TEXT		0x0020
#define MRTOBJ_FILL		0x0040

extern CRect DrawTextInRect(CDC* pDC, CString szString, LPRECT lpRect, long lHori, long lVert);

class CXMLSettings;
class CULDoc;

////////////////////////////////////////////////////////////////////////////////
// A simple container for rect position, and a base class for the user-objects.
//
class CMRTObject : public CObject
{
	DECLARE_SERIAL(CMRTObject)

	friend class CMRTOprt;
	friend class CMRTGroup;
	friend class CMRTUngroup;
public:
	static void InitClasses();
	static CMRTObject* CreateObj(LPCTSTR pszClassName);
	static CMRTObject* CreateObj(CXMLSettings& xml);
	static CPtrList m_lstClass; // Share classes
	
	CMRTObject();
	virtual ~CMRTObject();
	virtual CString GetObjType() { return _T("MRTObj"); }
	virtual void Serialize(CArchive& ar);
	virtual void Serialize(CXMLSettings& xml, DWORD dwProp = 0xFFFFFFFF);
	virtual DWORD GetEditProp() { return 0xFF78; }
	virtual int EditProp();
	virtual void Draw(CDC* pDC, CRect& rect);
	virtual void DrawTracker(CDC* pDC, CRect& rect)
	{
		rect.NormalizeRect();
		rect.InflateRect(+1, +1);   // borders are one pixel outside
		pDC->Rectangle(rect.left, rect.top, rect.right, rect.bottom);
	}
	virtual int HitTest(CPoint point, CDC* pDC, CRectTracker* pRectTracker);
	virtual int GetHandleCount() { return 8; }
	virtual void DrawHandle(CDC* pDC, CRect& rect);
	int HitTestLine(CPoint point, CPoint ptStart, CPoint ptEnd);

	LPCRECT GetRect()
	{
		return m_rectPosition;
	}

	int GetHeight()
	{
		return m_rectPosition.Height();
	}

	int GetWidth()
	{
		return m_rectPosition.Width();
	}

	CPoint TopLeft()
	{
		CPoint ptTopLeft;
		ptTopLeft.x = min(m_rectPosition.left, m_rectPosition.right);
		ptTopLeft.y = max(m_rectPosition.top, m_rectPosition.bottom);
		return ptTopLeft;
	}

	CPoint BottomRight()
	{
		CPoint ptBottomRight;
		ptBottomRight.x = max(m_rectPosition.left, m_rectPosition.right);
		ptBottomRight.y = min(m_rectPosition.top, m_rectPosition.bottom);
		return ptBottomRight;
	}

	virtual void GetCopyRect(CRect& rect)
	{
		rect = m_rectPosition;
	}

	virtual void SetRect(LPCRECT lpSrcRect);

	BOOL IsLocked()
	{
		return (m_dwLocked & 0x01);
	}

	BOOL IsReadonly()
	{
		return (m_dwLocked & 0x02);
	}

	void Lock(BOOL bLock = TRUE)
	{
		if (bLock)
			m_dwLocked |= 0x01;
		else
			m_dwLocked &= ~0x01;
	}

	void Readonly(BOOL bReadonly = TRUE)
	{
		if (bReadonly)
			m_dwLocked |= 0x02;
		else
			m_dwLocked &= ~0x02;
	}

	void SetText(LPCTSTR pszText)
	{
		if (!IsReadonly())
			m_strText = pszText;
	}

	void Draw(CDC* pDC, int nLayer = -1, int xOff = 0, int yOff = 0)
	{
		if (nLayer >=0)
		{
			// Not on this layer
			if (nLayer != m_nLayer)
				return;
		}

		CRect rect = GetRect();
		if (pDC->IsPrinting())
			xOff -= 32;
		rect.OffsetRect(xOff, yOff);
		Draw(pDC, rect);
	}

	// Line
	virtual long GetLineWidth() { return 0; }
	virtual void SetLineWidth(long lWidth) {}
	virtual long GetLineStyle() { return 0; }
	virtual void SetLineStyle(long lStyle) {}
	virtual COLORREF GetLineColor() { return (COLORREF)-1; }
	virtual void SetLineColor(COLORREF clrLine) {}
	virtual int GetLineArrow() { return 0; }
	virtual void SetLineArrow(int iArrow) {}

	// Text
	virtual CFont* GetFont() { return NULL; }
	virtual void SetFont(CFont* pFont) {}
	virtual long GetTextHorz() { return 0; }
	virtual void SetTextHorz(long lHorz) {}
	virtual long GetTextVert() { return 0; }
	virtual void SetTextVert(long lVert) {}
	virtual COLORREF GetTextColor() { return (COLORREF)-1; }
	virtual void SetTextColor(COLORREF clrText) {}
	virtual COLORREF GetTextBkColor() { return (COLORREF)-1; }
	virtual void SetTextBkColor(COLORREF clrTextBk) {}
	virtual CEdit* CreateInPlaceEdit(CRect rectEdit, CWnd* pWnd)
	{
		return NULL;
	}
	
	// Fill
	virtual CString GetPattern() { return _T(""); }
	virtual void SetPattern(LPCTSTR pszPattern) {}
    virtual BOOL GetUsePattern() { return FALSE; }
    virtual void SetUsePattern(BOOL bUse) {}

	virtual COLORREF GetFillColor() { return RGB(0, 0, 0); }
	virtual void SetFillColor(COLORREF clrFill) {}

	virtual COLORREF GetBkgColor() { return RGB(255,255,255); }
	virtual void SetBkgColor(COLORREF clrBkg) {}

	virtual CString GetPicFile() { return _T(""); }
	virtual void SetPicFile(LPCTSTR pszFile) {}

	virtual long GetPicHorz() { return 0; }
	virtual void SetPicHorz(long lHorz) {}
	virtual long GetPicVert() { return 0; }
	virtual void SetPicVert(long lVert) {}
	virtual long GetPicStyle() { return 0; }
	virtual void SetPicStyle(long lStyle) {}

	virtual long GetPicWidth() { return 0; }
	virtual void SetPicWidth(long lWidth) {}
	virtual long GetPicHeight() { return 0; }
	virtual void SetPicHeight(long lHeight) {}
	virtual CPoint GetPicOffset() { return CPoint(0, 0); }
	virtual void SetPicOffset(long xOffset, long yOffset) {}

	virtual void CreatePicture(LPCTSTR pszFile, HBITMAP hBitmap) {}

	// Charts
	virtual void SetDoc(IULFile* pDoc);

protected:
	virtual void GetHandleRect(int nHandle, CRect* pHandleRect, CDC* pDC);

public:
	CRect m_rectPosition;
	DWORD m_dwProp;
	DWORD m_dwLocked;
	int  m_nLayer;	// 0 -- 1
	CString m_strText;
	CList<CMRTObject*, CMRTObject*> m_lstChidren;
};

#define DA_BEGIN	0x0001
#define DA_END		0x0002

#define DA_A		0x0010	// <--------
#define DA_V		0x0020	// <*-------
#define DA_K		0x0100	// <|-------
#define DA_X		0x0200  // <<-------

#define DA_AK		(DA_A|DA_K)
#define DA_AKX		(DA_A|DA_K|DA_X)
#define DA_KX		(DA_K|DA_X)

class CLineObject : public CMRTObject
{
	DECLARE_SERIAL(CLineObject)
		
public:
	CLineObject();
	virtual ~CLineObject();
	
	virtual CString GetObjType() { return _T("LineObj"); }
	virtual void Serialize(CXMLSettings& xml, DWORD dwProp = 0xFFFFFFFF);
	virtual void Draw(CDC* pDC, CRect& rect);
	virtual void DrawTracker(CDC* pDC, CRect& rect)
	{
		// rect.InflateRect(+1, +1);   // borders are one pixel outside
		pDC->MoveTo(rect.TopLeft());
		pDC->LineTo(rect.BottomRight());
	}

	// Line
	virtual long GetLineWidth() { return m_iLineWidth; }
	virtual void SetLineWidth(long lWidth) {m_iLineWidth = lWidth;}
	virtual long GetLineStyle() { return m_iLineStyle; }
	virtual void SetLineStyle(long lStyle) {m_iLineStyle = lStyle;}
	virtual COLORREF GetLineColor() { return m_clrLine; }
	virtual void SetLineColor(COLORREF clrLine) {m_clrLine = clrLine;}
	virtual int GetLineArrow() { return m_dwArrow; }
	virtual void SetLineArrow(int iArrow) { m_dwArrow = iArrow; }
	virtual int GetArrowSize() { return m_iArrowSize; }
	virtual void SetArrowSize(int iArrowSize) { m_iArrowSize = iArrowSize; }

	virtual void GetCopyRect(CRect& rect)
	{
		rect = m_rectPosition;
		if (rect.Height() == 0)
		{
			if (m_dwArrow)
			{
				rect.top += 10;
				rect.bottom -= 10;
			}
			else
			{
				rect.top += 2;
				rect.bottom -= 2;
			}
		}
		else if (rect.Width() == 0)
		{
			if (m_dwArrow)
			{
				rect.left -= 10;
				rect.right += 10;
			}
			else
			{
				rect.left -= 2;
				rect.right += 2;
			}
		}
	}
	virtual int HitTest(CPoint point, CDC* pDC, CRectTracker* pRectTracker);
	virtual int GetHandleCount() { return 2; }
	virtual void GetHandleRect(int nHandle, CRect* pHandleRect, CDC* pDC);
	CPoint GetPointByLength(CPoint ptStart, double K, int nLen);
	void GetArrow(LPPOINT ptArrow, DWORD dwArraw, CPoint ptStart, CPoint ptEnd);
	
public:
	int	m_iLineWidth;
	int m_iLineStyle;
	COLORREF m_clrLine;
	DWORD m_dwArrow;
	int m_iArrowSize;
};

class CPolylineObject : public CLineObject
{
public:
	CPolylineObject();
	~CPolylineObject();
	virtual CString GetObjType() { return _T("PolylineObj"); }
	virtual void Serialize(CXMLSettings& xml, DWORD dwProp = 0xFFFFFFFF);
	virtual void Draw(CDC* pDC, CRect& rect);
	virtual void DrawTracker(CDC* pDC, CRect& rect);
	virtual int HitTest(CPoint point, CDC* pDC, CRectTracker* pRectTracker);
	virtual int GetHandleCount() { return m_points.GetSize(); }
	virtual void GetHandleRect(int nHandle, CRect* pHandleRect, CDC* pDC);
	virtual void SetRect(LPCRECT lpSrcRect);

public:
	CArray<CPoint,CPoint> m_points;
};

class CPolygonObject : public CPolylineObject
{
public:
	CPolygonObject();
	~CPolygonObject();
	virtual CString GetObjType() { return _T("PolygonObj"); }
	virtual void Serialize(CXMLSettings& xml, DWORD dwProp = 0xFFFFFFFF);
	virtual void Draw(CDC* pDC, CRect& rect);
	virtual void DrawTracker(CDC* pDC, CRect& rect);
	virtual int HitTest(CPoint point, CDC* pDC, CRectTracker* pRectTracker);
	
	// Fill
	virtual CString GetPattern() { return m_strPat; }
	virtual void SetPattern(LPCTSTR pszPattern) { m_strPat = pszPattern; }
    virtual BOOL GetUsePattern() { return TRUE; }
    //virtual void SetUsePattern(BOOL bUse) {}

	virtual COLORREF GetFillColor() { return m_clrFill; }
	virtual void SetFillColor(COLORREF clrFill) {m_clrFill = clrFill;}

	virtual COLORREF GetBkgColor() { return m_clrBkg; }
	virtual void SetBkgColor(COLORREF clrBkg) { m_clrBkg = clrBkg; }

public:
	COLORREF m_clrFill;
	COLORREF m_clrBkg;
	CString	m_strPat;
};

class CRectObject : public CLineObject, public CPicture
{
	DECLARE_SERIAL(CRectObject)
		
public:
	CRectObject();
	CRectObject(LPCRECT lpSrcRect)
	{
		InitRectObject();
		m_rectPosition = lpSrcRect;
		m_clrBk = RGB(255,255,255);
	}

	void InitRectObject();
	virtual ~CRectObject();

	CFont* GetDPFont()
	{
		return m_pDPFont;
	}	

	virtual CString GetObjType() { return _T("RectObj"); }
	virtual void Serialize(CXMLSettings& xml, DWORD dwProp = 0xFFFFFFFF);
	virtual void Draw(CDC* pDC, CRect& rect);
	virtual void DrawTracker(CDC* pDC, CRect& rect)
	{
		rect.InflateRect(+1, +1);   // borders are one pixel outside
		pDC->Rectangle(rect.left, rect.top, rect.right, rect.bottom);
	}

	// Text
	virtual CFont* GetFont() { return m_pFont; }
	virtual CFont* SelectFont(CDC* pDC);
	virtual void SetFont(CFont* pFont)
	{
		LOGFONT lf;
		ZeroMemory(&lf, sizeof(LOGFONT));
		pFont->GetLogFont(&lf);
		
		if (m_pFont)
			delete m_pFont;
		m_pFont = new CFont;
		m_pFont->CreateFontIndirect(&lf);

		if (m_pDPFont)
		{
			delete m_pDPFont;
			m_pDPFont = NULL;
		}
	}

	virtual long GetTextHorz() { return m_lHorz; }
	virtual void SetTextHorz(long lHorz) {m_lHorz = lHorz;}
	virtual long GetTextVert() { return m_lVert; }
	virtual void SetTextVert(long lVert) {m_lVert = lVert;}
	virtual COLORREF GetTextColor() { return m_clrText; }
	virtual void SetTextColor(COLORREF clrText) {m_clrText = clrText;}
	virtual COLORREF GetTextBkColor() { return m_clrBk; }
	virtual void SetTextBkColor(COLORREF clrTextBk) {m_clrBk = clrTextBk;}

	virtual CEdit* CreateInPlaceEdit(CRect rectEdit, CWnd* pWnd);
	
	// Fill
	virtual CString GetPattern() { return m_strPat; }
	virtual void SetPattern(LPCTSTR pszPattern) { m_strPat = pszPattern; }
    virtual BOOL GetUsePattern() { return m_bUsePattern; }
    virtual void SetUsePattern(BOOL bUse) { m_bUsePattern = bUse; }

	virtual COLORREF GetFillColor() { return m_clrFill; }
	virtual void SetFillColor(COLORREF clrFill) {m_clrFill = clrFill;}

	virtual COLORREF GetBkgColor() { return m_clrBkg; }
	virtual void SetBkgColor(COLORREF clrBkg) { m_clrBkg = clrBkg; }

	virtual CString GetPicFile() { return m_strFile; }
	virtual void SetPicFile(LPCTSTR pszFile)
	{
		m_strFile = pszFile;
		if (m_strFile.GetLength())
			LoadPicture(m_strFile);
		else
			FreePicture();
	}

	virtual long GetPicHorz() { return m_lHorzPic; }
	virtual void SetPicHorz(long lHorz) {m_lHorzPic = lHorz;}
	virtual long GetPicVert() { return m_lVertPic; }
	virtual void SetPicVert(long lVert) {m_lVertPic = lVert;}
	virtual long GetPicStyle() { return m_iSizeStyle; }
	virtual void SetPicStyle(long lStyle) {m_iSizeStyle = lStyle;}

	virtual long GetPicWidth() { return m_iWidthPic; }
	virtual void SetPicWidth(long lWidth) {m_iWidthPic = lWidth;}
	virtual long GetPicHeight() { return m_iHeightPic; }
	virtual void SetPicHeight(long lHeight) {m_iHeightPic = lHeight;}
	virtual CPoint GetPicOffset() { return m_ptOffset; }
	virtual void SetPicOffset(long xOffset, long yOffset)
	{
		m_ptOffset.x = xOffset;
		m_ptOffset.y = yOffset;
	}

	virtual void CreatePicture(LPCTSTR pszFile, HBITMAP hBitmap);

	virtual void GetCopyRect(CRect& rect)
	{
		rect = m_rectPosition;
		rect.right += 2;
		rect.bottom -= 2;
	}
	virtual int HitTest(CPoint point, CDC* pDC, CRectTracker* pRectTracker);
	virtual int GetHandleCount() { return 8; }
	virtual void GetHandleRect(int nHandle, CRect* pHandleRect, CDC* pDC)
	{
		CMRTObject::GetHandleRect(nHandle, pHandleRect, pDC);
	}

public:
	COLORREF m_clrText;
	COLORREF m_clrBk;

	COLORREF m_clrFill;
	COLORREF m_clrBkg;
	
	long m_lHorz;
	long m_lVert;
	CFont* m_pFont;
	CFont* m_pDPFont;

    BOOL m_bUsePattern; 
	CString	m_strPat;
	CString m_strFile;
	int m_iSizeStyle;
	long m_lHorzPic;
	long m_lVertPic;
	int m_iWidthPic;
	int m_iHeightPic;
	CPoint m_ptOffset;
};

class CEllipseObject : public CRectObject
{
public:
	CEllipseObject() {}
	virtual ~CEllipseObject() {}
	virtual CString GetObjType() { return _T("EllipseObj"); }
	virtual void Draw(CDC* pDC, CRect& rect);
};

class CPictureObject : public CRectObject
{
public:
    CPictureObject() { m_dwProp = 0x0040; } // Fill Only
    virtual ~CPictureObject() {}
    virtual CString GetObjType() { return _T("PictureObj"); }

    // text edit is not supported
    virtual CEdit* CreateInPlaceEdit(CRect rectEdit, CWnd* pWnd) { return NULL; } 
};

class CColumnObject : public CRectObject
{
public:
	CColumnObject();
	virtual ~CColumnObject() {}
	virtual CString GetObjType() { return _T("TableObj"); }
	virtual void SetRect(LPCRECT lpSrcRect);
	virtual void Draw(CDC* pDC, CRect& rect);
	void Print(CDC* pDC, CRect& rect);

public:
	CString strName;
	CString strUnit;
	CString strFormat;
	CStringArray strArray;
	CArray<double,double> dblArray;
};

typedef CList<CMRTObject*, CMRTObject*> CMRTObjList;
typedef CArray<CMRTObject*, CMRTObject*> CMRTObjArray;

extern CString m_strPatPath;
extern CBrush* SelectPatternBrush(CDC* pDC, CBrush* pBrush, LPCTSTR pszPattern, COLORREF clrFore, COLORREF clrBkg);
extern void DrawPattern(CDC* pDC, LPRECT lpRect, LPCTSTR pszPattern, COLORREF clrFore, COLORREF clrBkg);

#endif // !defined(AFX_MRTOBJECT_H__EAEC9766_0B79_4549_85A0_5136D758153A__INCLUDED_)
